package com.wj.facedetect.net;

import android.text.TextUtils;
import android.util.Log;

import com.wj.facedetect.util.CommonUtils;
import com.wj.facedetect.util.PreferencesUtils;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.builder.GetBuilder;
import com.zhy.http.okhttp.builder.OkHttpRequestBuilder;
import com.zhy.http.okhttp.builder.OtherRequestBuilder;
import com.zhy.http.okhttp.builder.PostFormBuilder;
import com.zhy.http.okhttp.builder.PostStringBuilder;
import com.zhy.http.okhttp.callback.BitmapCallback;
import com.zhy.http.okhttp.callback.Callback;
import com.zhy.http.okhttp.callback.FileCallBack;
import com.zhy.http.okhttp.callback.StringCallback;

import org.json.JSONException;
import org.json.JSONStringer;

import java.io.File;
import java.util.Map;

import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.RequestBody;

/**
 * Created by wujing on 2016/11/28.
 */
public class NetRequest {
    private static final String TAG = "NetRequest";
    private Object tag = "default";
    public static String KEY_SESSION_ID = "session_id";

    private NetRequest() {

    }

    public void setTag(Object tag) {
        this.tag = tag;
    }

    private static class RequestHolder {
        public static final NetRequest INSTANCE = new NetRequest();
    }

    public static NetRequest getInstance() {
        return RequestHolder.INSTANCE;
    }


    public void asynGet(String url, Map<String, String> args, BaseCallBack callback) {
        GetBuilder builder = OkHttpUtils.get().url(url);
        if (args != null) {
            for (Map.Entry<String, String> entry : args.entrySet()) {
                builder.addParams(entry.getKey(), entry.getValue());

            }
        }
        configHeader(builder);
        builder.tag(tag).build().execute(callback);
        Log.i(TAG, url + CommonUtils.changeMapToString(args));
    }

    //带有id的异步请求，id用于区分请求，防止请求错乱
    public void asynGet(String url, Map<String, String> args, Object tag, BaseCallBack callback) {
        GetBuilder builder = OkHttpUtils.get().url(url);
        if (args != null) {
            for (Map.Entry<String, String> entry : args.entrySet()) {
                builder.addParams(entry.getKey(), entry.getValue());
            }
        }
        configHeader(builder);
        builder.tag(tag).build().execute(callback);
        Log.i(TAG, url + CommonUtils.changeMapToString(args));
    }

    //带有id的异步请求，id用于区分请求，防止请求错乱
    public void asynGet(String url, Map<String, String> args, long tag, BaseCallBack callback) {
        GetBuilder builder = OkHttpUtils.get().url(url);
        if (args != null) {
            for (Map.Entry<String, String> entry : args.entrySet()) {
                builder.addParams(entry.getKey(), entry.getValue());
            }
        }
        configHeader(builder);
        builder.tag(tag).build().execute(callback);
        Log.i(TAG, url + CommonUtils.changeMapToString(args));
    }

    public void asynPost(String url, Map<String, String> args, BaseCallBack callback) {
        PostFormBuilder builder = OkHttpUtils.post().url(url);
        if (args != null) {
            for (Map.Entry<String, String> entry : args.entrySet()) {
                builder.addParams(entry.getKey(), entry.getValue());
            }
        }
        configHeader(builder);
        builder.tag(tag).build().execute(callback);
        Log.i(TAG, url + CommonUtils.changeMapToString(args));
    }

    public void asynPost(String url, Map<String, String> args, Object tag, BaseCallBack callback) {
        PostFormBuilder builder = OkHttpUtils.post().url(url);
        if (args != null) {
            for (Map.Entry<String, String> entry : args.entrySet()) {
                builder.addParams(entry.getKey(), entry.getValue());
            }
        }
        configHeader(builder);
        builder.tag(tag).build().execute(callback);
        Log.i(TAG, url + CommonUtils.changeMapToString(args));
    }


    public void asynDelete(String url, Map<String, String> args, long tag, BaseCallBack callback) {
        OtherRequestBuilder builder = OkHttpUtils.delete().url(url + "?id=" + args.get("id"));
        configHeader(builder);
        builder.tag(tag).build().execute(callback);
        Log.i(TAG, url + CommonUtils.changeMapToString(args));
    }

    public void asynDelete(String url, long tag, BaseCallBack callback) {
        OtherRequestBuilder builder = OkHttpUtils.delete().url(url);
        configHeader(builder);
        builder.tag(tag).build().execute(callback);
        Log.i(TAG, url);
    }

    public void asynPostJson(String url, Map<String, Object> args, BaseCallBack callback) {
        PostStringBuilder builder = OkHttpUtils.postString().url(url);
        if (args != null) {
            JSONStringer jsonStringer = null;
            try {
                jsonStringer = new JSONStringer().object();
                for (Map.Entry<String, Object> oneEntry : args.entrySet()) {
                    String key = oneEntry.getKey();
                    Object value = oneEntry.getValue();
                    jsonStringer.key(key).value(value);
                }
                jsonStringer.endObject();
                String jsonString = jsonStringer.toString();
                builder.content(jsonString).mediaType(MediaType.parse("application/json; charset=utf-8"));
                Log.i(TAG, url + jsonString);
            } catch (JSONException e) {
                Log.e(TAG, "asynPostJson: error", e);
            }
        } else {
            Log.i("tag", "args can't be empty");
        }
        configHeader(builder);
        builder.tag(tag).build().execute(callback);
    }

    public void asynPostJson(String url, Map<String, Object> args, Object tag, BaseCallBack callback) {
        PostStringBuilder builder = OkHttpUtils.postString().url(url);
        if (args != null) {
            JSONStringer jsonStringer = null;
            try {
                jsonStringer = new JSONStringer().object();
                for (Map.Entry<String, Object> oneEntry : args.entrySet()) {
                    String key = oneEntry.getKey();
                    Object value = oneEntry.getValue();
                    jsonStringer.key(key).value(value);
                }
                jsonStringer.endObject();
                String jsonString = jsonStringer.toString();
                builder.content(jsonString).mediaType(MediaType.parse("application/json; charset=utf-8"));
                Log.i(TAG, url + jsonString);
            } catch (JSONException e) {
                Log.e(TAG, "asynPostJson: error", e);
            }
        } else {
            Log.i("tag", "args can't be empty");
        }
        configHeader(builder);
        builder.tag(tag).build().execute(callback);
    }

    public void asynPostJson(String url, String jsonString, Object tag, BaseCallBack callback) {
        PostStringBuilder builder = OkHttpUtils.postString().url(url);
        if (jsonString != null) {
            builder.content(jsonString).mediaType(MediaType.parse("application/json; charset=utf-8"));
        } else {
            Log.i("tag", "args can't be empty");
        }
        configHeader(builder);
        Log.i(TAG, url + jsonString);
        builder.tag(tag).build().execute(callback);
    }

    //带有id的异步请求，id用于区分请求，防止请求错乱
    public void asynPostJson(String url, Map<String, String> args, int id, BaseCallBack callback) {
        PostStringBuilder builder = OkHttpUtils.postString().url(url);
        if (args != null) {
            JSONStringer jsonStringer = null;
            try {
                jsonStringer = new JSONStringer().object();
                for (Map.Entry<String, String> oneEntry : args.entrySet()) {
                    String key = oneEntry.getKey();
                    String value = oneEntry.getValue();
                    jsonStringer.key(key).value(value);
                }
                jsonStringer.endObject();
                String jsonString = jsonStringer.toString();
                builder.content(jsonString).mediaType(MediaType.parse("application/json; charset=utf-8"));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            Log.i("tag", "args can't be empty");
        }
        configHeader(builder);
        builder.tag(tag).id(id).build().execute(callback);
    }

    //带有id的异步请求，id用于区分请求，防止请求错乱
    public void asynPostJson(String url, String args, BaseCallBack callback) {
        PostStringBuilder builder = OkHttpUtils.postString().url(url);
        if (!TextUtils.isEmpty(args)) {
            builder.content(args).mediaType(MediaType.parse("application/json; charset=utf-8"));
        } else {
            Log.i("tag", "args can't be empty");
        }
        configHeader(builder);
        builder.tag(tag).id(100).build().execute(callback);
    }


    public void postFile(String url, File file, BaseCallBack callback) {
        OkHttpUtils.postFile().url(url).file(file).tag(tag).build().execute(callback);
    }

    public void postFile(String url, File file, int id, BaseCallBack callback) {
        OkHttpUtils.postFile().url(url).file(file).tag(tag).id(id).build().execute(callback);
    }

    public void postFileWithParams(String url, File file, int id, Map<String, String> params, BaseCallBack callback) {
        if (file == null) {
            Log.e("postFileWithParams", "file is null");
            return;
        }
        PostFormBuilder builder = OkHttpUtils.post();
        builder.addFile("file", file.getName(), file).url(url).id(id);
        if (params != null) {
            builder.params(params);
        }
        if (callback == null) {

            builder.build().execute(new StringCallback() {
                @Override
                public void onError(Call call, Exception e, int id) {

                }

                @Override
                public void onResponse(String response, int id) {

                }
            });
        } else {
            builder.build().execute(callback);
        }
    }

    public void cancelTagRequest(Object tag) {
        OkHttpUtils.getInstance().cancelTag(tag);
    }

    public void asynPut(String url, Map<String, String> args, BaseCallBack callback) {
        if (args != null) {
            JSONStringer jsonStringer = null;
            try {
                jsonStringer = new JSONStringer().object();
                for (Map.Entry<String, String> oneEntry : args.entrySet()) {
                    String key = oneEntry.getKey();
                    String value = oneEntry.getValue();
                    jsonStringer.key(key).value(value);
                }
                jsonStringer.endObject();
                String jsonString = jsonStringer.toString();
                OkHttpUtils.put().url(url).requestBody(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonString)).tag(tag).build().execute(callback);
                Log.i(TAG, url + CommonUtils.changeMapToString(args));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            Log.i("tag", "args can't be empty");
        }
    }

    public void asynPut(String url, Map<String, String> args, long tag, BaseCallBack callback) {
        OtherRequestBuilder otherRequestBuilder = OkHttpUtils.put().url(url);
        configHeader(otherRequestBuilder);
        if (args != null) {
            JSONStringer jsonStringer = null;
            try {
                jsonStringer = new JSONStringer().object();
                for (Map.Entry<String, String> oneEntry : args.entrySet()) {
                    String key = oneEntry.getKey();
                    String value = oneEntry.getValue();
                    jsonStringer.key(key).value(value);
                }
                jsonStringer.endObject();
                String jsonString = jsonStringer.toString();
                otherRequestBuilder.requestBody(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonString)).tag(tag).build().execute(callback);
                Log.i(TAG, url + CommonUtils.changeMapToString(args));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            Log.i("tag", "args can't be empty");
        }
    }

    public void asynPut(String url, String args, long tag, BaseCallBack callback) {
        OtherRequestBuilder otherRequestBuilder = OkHttpUtils.put().url(url);
        configHeader(otherRequestBuilder);
        if (args != null) {
            otherRequestBuilder.requestBody(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), args)).tag(tag).build().execute(callback);
            Log.i(TAG, url + args);
        } else {
            Log.i("tag", "args can't be empty");
        }
    }

    /**
     * 上传文件方法
     *
     * @param url      请求URL
     * @param file     要上传的文件
     * @param params   请求参数
     * @param callback 请求返回回调
     */
    public void postFileWithParams(String url, String fileName, File file, Map<String, String> params, Object tag, Callback callback) {
        if (callback == null) {
            return;
        }
        if (file == null) {
            return;
        }
        PostFormBuilder builder = OkHttpUtils.post();
        configHeader(builder);
        builder.addFile(fileName, file.getName(), file).url(url).tag(tag);
        if (params != null) {
            builder.params(params);
        }
        Log.d(TAG, "Post File: \n URL: " + url + " File: " + file.getAbsolutePath() + "\nParams: " + CommonUtils.changeMapToString(params));
        builder.tag(tag).build().execute(callback);
    }

    /**
     * @param url
     * @param fileCallBack 需要传入连个数据，文件的dir和文件名称
     */
    public void downFile(String url, Object tag, FileCallBack fileCallBack) {
        Log.i(TAG, url);
        OkHttpUtils.get().url(url).tag(tag).build().execute(fileCallBack);
    }

    /**
     * @param url
     * @param callback :可以直接在回调中操作UI，比如设置mImageView.setImageBitmap(bitmap);
     */
    public void downImage(String url, BitmapCallback callback) {
        OkHttpUtils
                .get()
                .url(url)
                .build()
                .execute(callback);
    }

    private void configHeader(OkHttpRequestBuilder builder) {
        builder.addHeader("Content-Type", "application/json");
        String sessionId = PreferencesUtils.getInstance().getSharePreStr(PreferencesUtils.SESSION_ID);
        if (sessionId != null) {
            builder.addHeader("session_id", sessionId);
            String[] tempArr = sessionId.split("@");
            if (tempArr != null && tempArr.length >= 2 && tempArr[1].isEmpty()) {
                builder.addHeader("yt_cluster_id", tempArr[1]);
            }
        }
    }

    /**
     * 取消请求
     *
     * @param tag
     */
    public void cancelRequestByTag(Object tag) {
        OkHttpUtils.getInstance().cancelTag(tag);
    }
}
